package com.stardata.liangshisq.tcslmon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.stardata.liangshisq.tcslmon.entity.*;
import com.stardata.liangshisq.tcslmon.mapper.*;
import com.stardata.liangshisq.tcslmon.service.KcKscService;
import com.stardata.liangshisq.tcslmon.service.SysParameterService;
import com.stardata.liangshisq.tcslmon.util.CommonConstants;
import com.stardata.liangshisq.tcslmon.util.CommonUtil;
import com.stardata.liangshisq.tcslmon.util.NoTimeArchItemUtil;
import lombok.AllArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * @author Samson Shu
 * @email shush@stardata.top
 * @date 2020/7/31 14:54
 */
@Service
@AllArgsConstructor
public class KcKscServiceImpl extends ServiceImpl<KcKscMapper, KcKsc> implements KcKscService {

    private final SysParameterService parameterService;
    private final KcKscMapper kcKscMapper;
    private final KcKscBakMapper kcKscBakMapper;
    private final BizBsMapper bizBsMapper;
    private final ArchItemMapper archItemMapper;
    private final ArchPointMapper archPointMapper;
    private final BizSsMapper bizSsMapper;

    @Override
    public List<Long> queryOrderIds(@NotNull Long shopId, Integer status, List<Long> areas, String orderBy) {
        QueryWrapper<KcKsc> wrapper = new QueryWrapper<>();
        wrapper.eq("create_shop_id", shopId).eq("kitchen_flg", status).orderByAsc("create_time");
        wrapper.apply("EXTRACT(epoch from (now()-create_time)) < 8*3600");
        if (orderBy == null) {
            wrapper.orderByAsc("create_time");
        } else if (orderBy.equals("create")) {
            wrapper.orderByAsc("create_time");
        } else if (orderBy.equals("prepare")) {
//      wrapper.orderByDesc("prepare_finish_time");
            wrapper.orderByDesc("create_time");
        } else if (orderBy.equals("passon")) {
//      wrapper.orderByDesc("serve_finish_time");
            wrapper.orderByDesc("create_time");
        }

        if (areas != null && areas.size() > 0) {
            StringBuilder bAreaIds = new StringBuilder();
            for (int i = 0; i < areas.size(); i++) {
                if (i > 0) bAreaIds.append(',');
                bAreaIds.append(areas.get(i).toString());
            }
            String inSql = String.format("select id from biz_bs b where b.point_id in (" + "select id from arch_point p where p.area_id in (%s) and p.delflg=0)", bAreaIds.toString());
            wrapper.inSql("bs_id", inSql);
        }
        List<KcKsc> kcKscList = kcKscMapper.selectList(wrapper);

        List<Long> result = new ArrayList<>();
        kcKscList.forEach(kcKsc -> {
            if (!result.contains(kcKsc.getBsId())) {
                result.add(kcKsc.getBsId());
            }
        });

        return result;
    }

    @Override
    public void prepareByList(@NotNull Long operUserId, @NotNull List<Long> kscIdList) {
        LocalDateTime now = LocalDateTime.now();
        for (Long kscId : kscIdList) {
            KcKsc kcKsc = kcKscMapper.selectById(kscId);
            if (kcKsc == null) continue;
            if (!kcKsc.getKitchenFlg().equals(CommonConstants.KitchenFlg.TO_PREPARE)) continue;

            kcKsc.setModifierId(operUserId);
            kcKsc.setModifyTime(now);

            kcKsc.setPrepareEmpId(operUserId);
            kcKsc.setPrepareFinishTime(now);

            kcKsc.setCookEmpId(operUserId);
            kcKsc.setCookFinishTime(now);

            kcKsc.setKitchenFlg(CommonConstants.KitchenFlg.TO_PASSON);

            kcKscMapper.updateById(kcKsc);
        }
    }

    @Override
    public void cancelPreparationByList(@NotNull Long operUserId, @NotNull List<Long> kscIdList) {
        LocalDateTime now = LocalDateTime.now();
        for (Long kscId : kscIdList) {
            KcKsc kcKsc = kcKscMapper.selectById(kscId);
            if (kcKsc == null) continue;
            if (!kcKsc.getKitchenFlg().equals(CommonConstants.KitchenFlg.TO_PASSON)) continue;

            kcKsc.setModifierId(operUserId);
            kcKsc.setModifyTime(now);

            kcKsc.setPrepareEmpId(null);
            kcKsc.setPrepareFinishTime(null);

            kcKsc.setCookEmpId(null);
            kcKsc.setCookFinishTime(null);

            kcKsc.setKitchenFlg(CommonConstants.KitchenFlg.TO_PREPARE);

            kcKscMapper.updateById(kcKsc);
        }
    }

    @Override
    public void passonByList(@NotNull Long operUserId, @NotNull List<Long> kscIdList) {
        LocalDateTime now = LocalDateTime.now();
        for (Long kscId : kscIdList) {
            KcKsc kcKsc = kcKscMapper.selectById(kscId);
            if (kcKsc == null) continue;

            kcKsc.setModifierId(operUserId);
            kcKsc.setModifyTime(now);

            kcKsc.setServeEmpId(operUserId);
            kcKsc.setServeFinishTime(now);

            kcKsc.setKitchenFlg(CommonConstants.KitchenFlg.PRODUCED);

            kcKscMapper.updateById(kcKsc);
        }
    }

    @Override
    public void cancelPassonByList(Long operUserId, List<Long> kscIdList) {
        LocalDateTime now = LocalDateTime.now();
        for (Long kscId : kscIdList) {
            KcKsc kcKsc = kcKscMapper.selectById(kscId);
            if (kcKsc == null) continue;
            if (!kcKsc.getKitchenFlg().equals(CommonConstants.KitchenFlg.PRODUCED)) continue;

            kcKsc.setModifierId(operUserId);
            kcKsc.setModifyTime(now);

            kcKsc.setServeEmpId(null);
            kcKsc.setServeFinishTime(null);

            kcKsc.setKitchenFlg(CommonConstants.KitchenFlg.TO_PASSON);

            kcKscMapper.updateById(kcKsc);
        }
    }

    @Override
    public List<ProductVo> queryCancelableItems(@NotNull Long shopId, @NotNull Integer status, List<Long> areas) {
        QueryWrapper<KcKsc> kcKscQueryWrapper = new QueryWrapper<>();
        kcKscQueryWrapper.eq("create_shop_id", shopId);
        //只查询8小时内的记录
        LocalDateTime now = LocalDateTime.now();
        kcKscQueryWrapper.between("create_time", now.with(LocalTime.MIN), now.with(LocalTime.MAX));
        if (status.equals(CommonConstants.KitchenFlg.TO_PASSON)) {
            // 查询配的数据
            kcKscQueryWrapper.isNotNull("cook_finish_time").orderByDesc("cook_finish_time");
        } else if (status.equals(CommonConstants.KitchenFlg.PRODUCED)) {
            // 查询传的数据
            kcKscQueryWrapper.isNotNull("serve_finish_time").orderByDesc("serve_finish_time");
        }
        if (areas != null && areas.size() > 0) {
            StringBuilder bAreaIds = new StringBuilder();
            for (int i = 0; i < areas.size(); i++) {
                if (i > 0) bAreaIds.append(',');
                bAreaIds.append(areas.get(i).toString());
            }
            String inSql = String.format("select id from biz_bs b where b.point_id in (" + "select id from arch_point p where p.area_id in (%s) and p.delflg=0)", bAreaIds.toString());
            kcKscQueryWrapper.inSql("bs_id", inSql);
        }
        List<KcKsc> kcKscList = kcKscMapper.selectList(kcKscQueryWrapper);

        List<Long> onlineAreaIds = parameterService.getListByCode("onlineAreaIds", Long.class);
        List<ProductVo> result = new ArrayList<>();
        for (KcKsc kcKsc : kcKscList) {
            ProductVo product = new ProductVo();
            List<Long> kscIds = new ArrayList<>();
            kscIds.add(kcKsc.getId());
            product.setKscIds(kscIds);
            product.setItemId(kcKsc.getItemId().toString());
            product.setStatus(kcKsc.getKitchenFlg());

            ArchItem archItem = archItemMapper.selectById(kcKsc.getItemId());
            if (archItem == null) {
                product.setItemName(kcKsc.getTempItemName());
                product.setItemId(kcKsc.getItemId() + kcKsc.getTempItemName());
            } else {
                product.setItemName(archItem.getName());
            }

            BizBs bizBs = bizBsMapper.selectById(kcKsc.getBsId());
            if (bizBs == null) continue;

            ArchPoint archPoint = archPointMapper.selectById(bizBs.getPointId());
            if (archPoint == null) continue; //没有桌位编码的订单，可以忽略

            product.setTableNo(archPoint.getCode());
            product.setTableName(archPoint.getName());
            product.setSourceType(onlineAreaIds.contains(archPoint.getAreaId()) ? CommonConstants.OrderSourceType.ONLINE : CommonConstants.OrderSourceType.OFFLINE);
            product.setOrigQty(kcKsc.getOrigQty());
            product.setLastQty(kcKsc.getLastQty());
            product.setMethod(CommonUtil.methodText2List(kcKsc.getMethodText()));
            product.setOrderTime(kcKsc.getCreateTime());
            //如果是"待传菜"状态，则操作时间是配菜时间；如果是"已传菜"状态，则操作时间是配菜时间；
            if (status.equals(CommonConstants.KitchenFlg.TO_PASSON)) {
                product.setOperTime(kcKsc.getCookFinishTime());
            } else if (status.equals(CommonConstants.KitchenFlg.PRODUCED)) {
                product.setOperTime(kcKsc.getServeFinishTime());
            }
            result.add(product);
        }
        result.sort(new Comparator<ProductVo>() {
            @Override
            public int compare(ProductVo o1, ProductVo o2) {
                return o2.getOperTime().compareTo(o1.getOperTime());
            }
        });
        return result;
    }

    @NotNull
    @Override
    public List<KcKsc> selectByBsId(@NotNull Long bsId) {
        QueryWrapper<KcKsc> wrapper = new QueryWrapper<>();
        wrapper.eq("bs_id", bsId);
        wrapper.orderBy(true, true, "kitchen_flg");
        return kcKscMapper.selectList(wrapper);
    }

    @NotNull
    @Override
    public List<KcKsc> selectByBsIds(List<Long> bsIds) {
        QueryWrapper<KcKsc> wrapper = new QueryWrapper<>();
        wrapper.in("bs_id", bsIds);
        return kcKscMapper.selectList(wrapper);
    }

    @NotNull
    @Override
    public List<KcKsc> selectByKcKscIds(@NotNull List<Long> kcKscIds) {
        if (kcKscIds.size() < 1) return new ArrayList<>();
        QueryWrapper<KcKsc> wrapper = new QueryWrapper<>();
        wrapper.in("id", kcKscIds);
        return kcKscMapper.selectList(wrapper);
    }

    /**
     * 查询订单的所有菜品没有加工的最早一笔订单
     *
     * @param bsId 指定的营业流水ID
     * @return
     */
    @Override
    public KcKsc getFirstByBsId(@NotNull Long bsId) {
        QueryWrapper<KcKsc> wrapper = new QueryWrapper<>();
        List<Long> noTimeArchIds = NoTimeArchItemUtil.noTimeArchItem();
        wrapper.eq("bs_id", bsId).ne("kitchen_flg", 3).notIn("item_id", noTimeArchIds)
                // if (itemVo.getLastQty() == 0) continue; //如果数量为零，直接跳过
                .ne("last_qty", 0).orderByAsc("call_up_time");
        List<KcKsc> kcKscs = kcKscMapper.selectList(wrapper);
        if (kcKscs.size() < 1) return null;
        return kcKscs.get(0);
    }

    @Override
    @Nullable
    public ProductVo convertToProductVo(@NotNull KcKsc kcKsc) {
        if (kcKsc.getLastQty().doubleValue() < 0.001) return null;

        List<Long> onlineAreaIds = parameterService.getListByCode("onlineAreaIds", Long.class);
        List<Long> retailAreaIds = parameterService.getListByCode("retailAreaIds", Long.class);
        ProductVo productVo = new ProductVo();

        productVo.setBsId(kcKsc.getBsId());
        List<Long> kscIds = new ArrayList<>();
        kscIds.add(kcKsc.getId());
        productVo.setKscIds(kscIds);
        ArchItem archItem = archItemMapper.selectById(kcKsc.getItemId());
        if (archItem == null || archItem.getIsTempItem()) {
            productVo.setItemId(kcKsc.getItemId().toString() + kcKsc.getTempItemName());
            productVo.setItemName(kcKsc.getTempItemName());
        } else {
            productVo.setItemId(kcKsc.getItemId().toString());
            productVo.setItemName(archItem.getName());
        }
        if (archItem == null) {
            productVo.setStatus(kcKsc.getKitchenFlg());
        } else {
            if (KitchenQueryUtil.getKdsClassIds().contains(archItem.getSmallClassId())) {
                productVo.setStatus(kcKsc.getKitchenFlg());
            } else {
                productVo.setStatus(-1);
            }
        }

        BizBs bizBs = bizBsMapper.selectById(kcKsc.getBsId());
        if (bizBs == null) return null;

        String remark = "";
        QueryWrapper<BizSs> bizSsQueryWrapper = new QueryWrapper<>();
        bizSsQueryWrapper.eq("bs_id", kcKsc.getBsId());
        List<BizSs> bizSsList = bizSsMapper.selectList(bizSsQueryWrapper);
        if (bizSsList.size() > 0) {
            remark = bizSsList.get(0).getSsRemark();
        }
        productVo.setRemark(remark);

        ArchPoint archPoint = archPointMapper.selectById(bizBs.getPointId());
        if (archPoint == null) return null;

        productVo.setTableNo(archPoint.getCode());
        productVo.setTableName(archPoint.getName());

        if (onlineAreaIds.contains(archPoint.getAreaId())) {
            productVo.setSourceType(CommonConstants.OrderSourceType.ONLINE);
        } else if (retailAreaIds.contains(archPoint.getAreaId())) {
            productVo.setSourceType(CommonConstants.OrderSourceType.RETAIL);
        } else {
            productVo.setSourceType(CommonConstants.OrderSourceType.OFFLINE);
        }
        productVo.setOrigQty(kcKsc.getOrigQty());
        productVo.setLastQty(kcKsc.getLastQty());
        productVo.setMethod(CommonUtil.methodText2List(kcKsc.getMethodText()));
        productVo.setOrderTime(kcKsc.getCreateTime());
        //如果是"待传菜"状态，则操作时间是配菜时间；如果是"已传菜"状态，则操作时间是配菜时间；
        if (kcKsc.getKitchenFlg().equals(CommonConstants.KitchenFlg.TO_PASSON)) {
            productVo.setOperTime(kcKsc.getPrepareFinishTime());
        } else if (kcKsc.getKitchenFlg().equals(CommonConstants.KitchenFlg.PRODUCED)) {
            productVo.setOperTime(kcKsc.getServeFinishTime());
        }
        return productVo;
    }

    @Override
    public List<KcKsc> queryKscSendData(Long bizBsId) {
        QueryWrapper<KcKsc> wrapper = new QueryWrapper<>();
        wrapper.eq("bs_id", bizBsId);
        List<KcKsc> kcKscList = kcKscMapper.selectList(wrapper);
        if (kcKscList.isEmpty()) {
            QueryWrapper<KcKscBak> wrapperbak = new QueryWrapper<>();
            wrapperbak.eq("bs_id", bizBsId);
            List<KcKscBak> kcKscBakList = (List<KcKscBak>) kcKscBakMapper.selectList(wrapperbak);
            for (KcKscBak item : kcKscBakList) {
                KcKsc kcKsc = new KcKsc();
                BeanUtils.copyProperties(item, kcKsc);
                kcKscList.add(kcKsc);
            }
        }
        return kcKscList;
    }

    @Override
    public void updateOpenTime(Long bsId) {
        kcKscMapper.updateOpenTime(bsId);
    }

}
